package reflect;


import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @description: 通过反射创建对象的几种方式
 * @author: apple
 * @date:  2021/12/26 2:36 下午
 * @version 1.0
 **/
public class ReflectInstance {


    @Test
    public void test2() throws ClassNotFoundException {
        // 获取运行时类实例的四种方式

        // 1、方式1、通过classs属性来获取
        Class<Table> tableClass = Table.class;

        // 2、方式2、通过对象来获取
        Class<? extends Table> aClass = new Table().getClass();

        // 3、方式3、通过Class的静态方法
        Class<?> aClass1 = Class.forName("reflect.ReflectInstance$Table");
        System.out.println(aClass1);

        System.out.println(tableClass == aClass);
        System.out.println(aClass == aClass1);

        // 4、方式4、通过类加载器
        ClassLoader classLoader = ReflectInstance.class.getClassLoader();
        Class<?> aClass2 = classLoader.loadClass("reflect.ReflectInstance");
        System.out.println(aClass2);

        Class<int[]> aClass4 = int[].class;
        System.out.println(aClass4);

        Class<Void> voidClass = void.class;
        System.out.println(voidClass);

    }


    class Table {

        private int id;
        public String name;

        public Table(int id, String name) {
            this.id = id;
            this.name = name;
        }

        private Table(String name) {
            this.name = name;
        }

        public Table() {
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


        public void show() {
            System.out.println("大家好，我是桌子：" + name);
        }

        private String  card(String t) {
            System.out.println("id号码是：" + t);
            return "count" + t;
        }

        @Override
        public String toString() {
            return "Table{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    @Test
    public void test1() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        // 一、通过反射创建对象
        // 获取类的类对象
        Class<Table> tableClass = Table.class;
        // 获取构造器对象
        Constructor<Table> constructor = tableClass.getDeclaredConstructor(int.class, String.class);
        // 造对象
        final Table obj = constructor.newInstance(1, "金丝楠木");

        System.out.println(obj);


        // 二、通过反射调用属性和方法
        Field name = tableClass.getDeclaredField("name");
        // 调用obj对象的这个属性
        name.set(obj, "乌木");
        System.out.println(obj);

        Method show = tableClass.getDeclaredMethod("show");
        // 调用obj对象的这个方法
        show.invoke(obj);

        // 三、通过反射调用私有构造器、属性、方法
        Constructor<Table> constructor1 = tableClass.getDeclaredConstructor(String.class);
        constructor1.setAccessible(true);
        Table obj2 = constructor1.newInstance("定制");
        System.out.println(obj2);

        // 调用私有属性
        Field id = tableClass.getDeclaredField("id");
        id.setAccessible(true);
        id.set(obj2,99);
        System.out.println(obj2);
        
        // 调用私有方法
        Method card = tableClass.getDeclaredMethod("card" , String.class);
        card.setAccessible(true);
        Object returnValue = card.invoke(obj2, "9898989");
        System.out.println(returnValue);


    }



}


